home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / plugins / mapquake3entitylines.py < prev    next >
Text File  |  2004-01-05  |  10KB  |  238 lines

  1. """   QuArK  -  Quake Army Knife
  2. """
  3. #
  4. # Copyright (C) 1996-99 Armin Rigo
  5. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  6. # FOUND IN FILE "COPYING.TXT"
  7. #
  8.  
  9. #$Header: /cvsroot/quark/runtime/plugins/mapquake3entitylines.py,v 1.3 2002/12/29 12:45:17 decker_dk Exp $
  10.  
  11. Info = {
  12.    "plug-in":       "Quake-3 Arrow Extensions",
  13.    "desc":          "Displays axis for rotating entities and jump-archs for push-entities. Note: RED-colored jump-archs indicates that the jump isn't correctly calculated, due to either non-default gravity or too low an arch.",
  14.    "date":          "2 jan 2001",
  15.    "author":        "Decker",
  16.    "author e-mail": "decker@post1.tele.dk",
  17.    "quark":         "Version 6.3" }
  18.  
  19.  
  20. import math
  21. from quarkpy.maputils import *
  22. import quarkpy.mapentities
  23. import quarkpy.qeditor
  24. import quarkpy.qhandles
  25.  
  26. DefaultDrawEntityLines = quarkpy.mapentities.DefaultDrawEntityLines
  27. ObjectOrigin = quarkpy.mapentities.ObjectOrigin
  28.  
  29. import plugins.deckerutils
  30. FindOriginFlagPolyPos = plugins.deckerutils.FindOriginFlagPolyPos
  31.  
  32. class Quake3DrawEntityLines(DefaultDrawEntityLines):
  33.  
  34.    # - Decker. Trying to calculate a more correct jump-arch, using the math from Q3's GameSource,
  35.    #   but I simply can't figure out how to do that.
  36.    #
  37.    #def CalculateTrajectory2(self, start_vec, apex_vec, speed_angles, gravity=800.0, multiplier=2, points=16):
  38.    #    path_vecs = []
  39.    #    try:
  40.    #        if (apex_vec is not None):
  41.    #            height = apex_vec.z - start_vec.z
  42.    #            if (height <= 0 or gravity <= 0):
  43.    #                raise "Problem!"
  44.    #            time = math.sqrt( height / ( 0.5 * gravity ) );
  45.    #            if (time <= 0):
  46.    #                raise "Problem!"
  47.    #            direction_vec = apex_vec - start_vec
  48.    #            direction_vec = quarkx.vect(direction_vec.x, direction_vec.y, 0)
  49.    #            direction_vec = direction_vec.normalized
  50.    #            forward = abs(direction_vec) / time
  51.    #            velocity_vec = direction_vec * forward
  52.    #            velocity_vec = quarkx.vect(velocity_vec.x, velocity_vec.y, time * gravity)
  53.    #        else:
  54.    #            speed_z, angles = speed_angles
  55.    #            direction_vec = quarkpy.qhandles.angles2vec(angles)
  56.    #            direction_vec = quarkx.vect(direction_vec.x, direction_vec.y, 0)
  57.    #            direction_vec = direction_vec.normalized
  58.    #            velocity_vec = direction_vec * speed_z
  59.    #            velocity_vec = quarkx.vect(velocity_vec.x, velocity_vec.y, speed_z)
  60.    #        print "direction:", direction_vec, "velocity:", velocity_vec
  61.    #    except:
  62.    #        print "Exception:"
  63.    #    return path_vecs, color
  64.  
  65.     def CalculateTrajectory(self, start_vec, apex_vec, speed_angles, gravity=800.0, multiplier=2, points=16):
  66.         # Credits to "http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/bobtoolz/bobtoolz/DBobView.cpp"
  67.         path_vecs = []
  68.         color = 0x000000
  69.         etext = None
  70.         try:
  71.             dist_vec = None
  72.             speed_z = 0
  73.  
  74.             if (apex_vec is not None):
  75.                 # Calculate a distance-vector between the start-vector and the apex-vector
  76.                 dist_vec = apex_vec - start_vec
  77.  
  78.                 # If the distance-vector's z-axis is zero or negative, then we can't calculate a proper flight-arch
  79.                 if (dist_vec.z <= 0):
  80.                     etext = "Can't calculate with zero/negative z-distance"
  81.                     raise etext
  82.  
  83.                 # Calculate the z-axis speed at normal gravity (800.0)
  84.                 speed_z = math.sqrt(2 * gravity * dist_vec.z)
  85.             else:
  86.                 if (gravity != 800):
  87.                     # This calculation won't work with another gravity setting.
  88.                     color = 0x0000FF
  89.                     print "Trigger_push/Target_push: Gravity isn't 800.0, so jump-arch is not calculated correctly"
  90.  
  91.                 speed_z, angles = speed_angles
  92.                 speed_z = math.sqrt(gravity * speed_z)
  93.                 dist_vec = quarkpy.qhandles.angles2vec(angles)
  94.  
  95.                 if (dist_vec.z < 0.7):
  96.                     # This calculation won't work with a pitch lower than ~45
  97.                     color = 0x0000FF
  98.                     print "Trigger_push/Target_push: pitch-angle is less than 45, so jump-arch is not calculated correctly"
  99.  
  100.                 dist_vec = dist_vec.normalized * speed_z
  101.  
  102.             # Calculate the time it will take to make the "flight" at normal gravity (800.0)
  103.             flight_time = speed_z / gravity
  104.  
  105.             # Calculate the speed-distance-vector of one unit of flight_time
  106.             speed_vec = dist_vec * (1 / flight_time)
  107.  
  108.             # Adjust the z-axis of the speed-distance-vector
  109.             speed_vec = quarkx.vect(speed_vec.x, speed_vec.y, speed_z)
  110.  
  111.             # Determine the flighttime-interval between each point
  112.             interval = (multiplier * flight_time) / points
  113.  
  114.             # Calculate each point in the flight-path
  115.             for i in range(points+1):
  116.                 # Compute the flighttime for this point
  117.                 ltime = interval * i
  118.  
  119.                 # Calculate a point in the linear(straight) line from start-vector to end-vector
  120.                 path_vec = speed_vec * ltime
  121.                 path_vec = path_vec + start_vec
  122.  
  123.                 # Adjust the z-axis
  124.                 z = start_vec.z + (speed_z * ltime) - (gravity * 0.5 * ltime * ltime)
  125.                 path_vec = quarkx.vect(path_vec.x, path_vec.y, z)
  126.  
  127.                 # Put this point in the list
  128.                 path_vecs.append(path_vec)
  129.         except etext:
  130.             print "exception:", etext
  131.  
  132.         return path_vecs, color
  133.  
  134.     def showjumparch(self, start_entity, view, entities):
  135.         apex_vec = None
  136.         speed_angles = None
  137.         if (start_entity["target"] is not None \
  138.         and start_entity["target"] != ""):
  139.             apex_entity = None
  140.             for e in entities:
  141.                 if (e["targetname"] == start_entity["target"]):
  142.                     apex_vec = ObjectOrigin(e)
  143.                     break
  144.             else:
  145.                 return
  146.         else:
  147.             speed = 1000 # Default value according to [DataQ3.QRK] target_push:form
  148.             if (start_entity["speed"] is not None \
  149.             and start_entity["speed"] != ""):
  150.                 speed = int(start_entity["speed"])
  151.             angles = None
  152.             if (start_entity["angles"] is not None):
  153.                 angles = start_entity["angles"]
  154.             if (angles is None):
  155.                 return
  156.             speed_angles = (speed, angles)
  157.         start_vec = ObjectOrigin(start_entity)
  158.  
  159.         editor = quarkpy.qeditor.mapeditor()
  160.         if editor is None:
  161.             return
  162.         worldspawn = editor.Root
  163.         gravity = 800.0
  164.         if (worldspawn["gravity"] is not None \
  165.         and worldspawn["gravity"] != ""):
  166.             gravity = int(worldspawn["gravity"])
  167.  
  168.         path, color = self.CalculateTrajectory(start_vec, apex_vec, speed_angles, gravity)
  169.         if len(path) > 0:
  170.             cv = view.canvas()
  171.             cv.pencolor = color
  172.             cv.penwidth = 3
  173.             prevpath = None
  174.             for p in path:
  175.                 thispath = view.proj(p)
  176.                 if prevpath is not None:
  177.                     cv.line(prevpath, thispath)
  178.                 prevpath = thispath
  179.  
  180.     def showoriginline(self, entity, xaxisbitvalue, yaxisbitvalue, view, color):
  181.         orgpos = FindOriginFlagPolyPos(entity)
  182.         if orgpos is not None:
  183.             try:
  184.                 axisflags = int(entity["spawnflags"])
  185.             except:
  186.                 axisflags = 0
  187.             axisdist = quarkx.vect(0, 0, 0)
  188.             if axisflags & xaxisbitvalue:
  189.                 axisdist = quarkx.vect(16, 0, 0) # 16 is just some appropriate value I choosed
  190.             elif axisflags & yaxisbitvalue:
  191.                 axisdist = quarkx.vect(0, 16, 0)
  192.             else:
  193.                 axisdist = quarkx.vect(0, 0, 16)
  194.             cv = view.canvas()
  195.             cv.pencolor = color
  196.             cv.penwidth = 3 # So it the axis gets more visual
  197.             pos1, pos2 = (orgpos + axisdist), (orgpos - axisdist)
  198.             vpos1, vpos2 = view.proj(pos1), view.proj(pos2)
  199.             cv.line(vpos1, vpos2)
  200.  
  201.     def drawentitylines(self, entity, org, view, entities, processentities):
  202.         # Draw the default target/targetname/killtarget/light/_light arrows/ellipse
  203.         DefaultDrawEntityLines.drawentitylines(self, entity, org, view, entities, processentities)
  204.         # From here its Quake-3 special
  205.         axiscolor = quarkpy.qeditor.MapColor("Axis")
  206.         rotcolor = 0xff00ff     # (magenta) rotation axis
  207.         org1 = view.proj(org)
  208.         if org1.visible:
  209.             if entity.name == "func_rotating:b":
  210.                 self.showoriginline(entity, 1, 2, view, rotcolor) # func_rotating has different bitvalues for X-axis and Y-axis
  211.             elif entity.name == "func_pendulum:b":
  212.                 self.showoriginline(entity, 0, 0, view, rotcolor)
  213.             elif entity.name == "trigger_push:b":
  214.                 self.showjumparch(entity, view, entities)
  215.             elif entity.name == "target_push:e":
  216.                 self.showjumparch(entity, view, entities)
  217.  
  218. #
  219. # Register this class with its gamename
  220. #
  221. quarkpy.mapentities.EntityLinesMapping.update({
  222.   "Quake 3": Quake3DrawEntityLines()
  223. })
  224.  
  225. # ----------- REVISION HISTORY ------------
  226. #
  227. # $Log: mapquake3entitylines.py,v $
  228. # Revision 1.3  2002/12/29 12:45:17  decker_dk
  229. # A description in the plugin-infoarea, about what the black/red colors of the jump-archs mean.
  230. #
  231. # Revision 1.2  2002/12/28 14:03:54  decker_dk
  232. # Added some jump-arch kindof entity-lines for 'trigger_push' and 'target_push'. Some of the math ain't correct.
  233. #
  234. # Revision 1.1  2001/01/30 19:20:30  decker_dk
  235. # Basically a copy of mapquake2entitylines.py
  236. #
  237. #
  238.